package com.psytech.app.task.tasks_mds.service;

import taskmanager.psytech.com.taskmanagerservice._2.Comment;
import taskmanager.psytech.com.taskmanagerservice._2.CommentList;
import taskmanager.psytech.com.taskmanagerservice._2.Task;
import taskmanager.psytech.com.taskmanagerservice._2.TaskList;
import taskmanager.psytech.com.taskmanagerservice._2.Todo;
import taskmanager.psytech.com.taskmanagerservice._2.UserUidList;

import com.psytech.app.task.tasks_mds.service.exception.BusinessException;
import com.psytech.app.task.tasks_mds.service.exception.TechnicalException;

public interface TaskMasterDataService {

	/**
	 * Create a new task in the repository. At least, the name and the creator
	 * uid must be provided.
	 * 
	 * @param task
	 *            to create
	 * @return created task
	 * @throws BusinessException
	 *             if properties name or creatorUis are missing
	 * @throws TechnicalException
	 *             if a problem occurs at insertion time.
	 */
	Task createTask(Task task) throws BusinessException, TechnicalException;

	/**
	 * Delete a task in the repository. The uid must be specified.
	 * 
	 * @param task
	 *            to delete
	 * @throws BusinessException
	 *             if property uid is missing
	 * @throws TechnicalException
	 *             if a problem occurs at deletion time.
	 */
	void deleteTask(Task task) throws BusinessException, TechnicalException;

	/**
	 * Search all task matching the given taskCriteria.
	 * 
	 * @param taskCriteria
	 *            , each field is a criteria.
	 * @return A task List.
	 * @throws TechnicalException
	 *             if a problem occurs at query time.
	 */
	TaskList searchTask(Task taskCriteria) throws TechnicalException;

	/**
	 * Update task category.
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing or description does not respect
	 *             the rules of persistence
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task updateTaskCategory(Task task) throws BusinessException, TechnicalException;

	/**
	 * Update task description.
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing or description does not respect
	 *             the rules of persistence
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task updateTaskDescription(Task task) throws BusinessException, TechnicalException;

	/**
	 * Update task name
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing or name does not respect the rules
	 *             of persistence
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task updateTaskName(Task task) throws BusinessException, TechnicalException;

	/**
	 * Set task status to PROGRESS and update the start date
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing.
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task startTask(Task task) throws BusinessException, TechnicalException;

	/**
	 * Set task status to PENDING.
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing.
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task suspendTask(Task task) throws BusinessException, TechnicalException;

	/**
	 * Set task status to COMPLETE and update the end date
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task completeTask(Task task) throws BusinessException, TechnicalException;

	/**
	 * Update the expected start date
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing or start date does not respect the
	 *             rules of persistence
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task updateExpectedStartDate(Task task) throws BusinessException, TechnicalException;

	/**
	 * Update the expected end date
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing or end date does not respect the
	 *             rules of persistence
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task updateExpectedEndDate(Task task) throws BusinessException, TechnicalException;

	/**
	 * Set the priority to HIGH
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing.
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task increasePriority(Task task) throws BusinessException, TechnicalException;

	/**
	 * Set the priority to LOW
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing.
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task lowPriority(Task task) throws BusinessException, TechnicalException;

	/**
	 * Set thepriority to NORMAL.
	 * 
	 * @param task
	 * @return updated task
	 * @throws BusinessException
	 *             if property uid is missing.
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task unspecifyPriority(Task task) throws BusinessException, TechnicalException;

	/**
	 * Get all task assign to the given user uid list.
	 * 
	 * @param usersUid
	 * @return A task List.
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	TaskList searchTasksAssignedToUsers(UserUidList usersUid) throws TechnicalException;

	/**
	 * Assign users to the specified task.
	 * 
	 * @param todo
	 * @return the assigned task.
	 * @throws BusinessException
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task assignUsersToTask(Todo todo) throws BusinessException, TechnicalException;

	/**
	 * Unassign users to thespecifies task.
	 * 
	 * @param todo
	 * @return the updated task.
	 * @throws BusinessException
	 * @throws TechnicalException
	 *             if a problem occurs at update time.
	 */
	Task unassignedUsersToTask(Todo todo) throws BusinessException, TechnicalException;

	/**
	 * Delete the given comment if exists.
	 * 
	 * @param comment
	 *            with a least the uid.
	 * @throws BusinessException
	 * @throws TechnicalException
	 */
	void deleteComment(Comment comment) throws BusinessException, TechnicalException;

	/**
	 * @param comment
	 *            , the comment to persist.
	 * @return the new Comment
	 * @throws BusinessException
	 * @throws TechnicalException
	 */
	Comment createComment(Comment comment) throws BusinessException, TechnicalException;

	/**
	 * Return all comments linked to a task. They are ordered by freshness.
	 * 
	 * @param task
	 *            , a task with at least the uid.
	 * @return all comments linked to a task. They are ordered by freshness.
	 * @throws BusinessException
	 * @throws TechnicalException
	 */
	CommentList getCommentsByTask(Task task) throws BusinessException, TechnicalException;
}
